import json
from flask import request
from .base import BaseLogger


class RequestLogger(BaseLogger):
    """
    HTTP请求专用日志器，专门用于记录HTTP请求和响应信息
    """
    
    def __init__(self):
        """
        初始化请求日志器
        
        Args:
            name: 日志器名称，会被忽略，强制使用'request'
        """
        # 强制使用'request'作为logger名称，以确保使用正确的配置
        super().__init__('request')
    
    def log_request_start(self, request_obj=None):
        """
        记录请求开始
        
        Args:
            request_obj: Flask request对象，如果为None则使用全局request
        """
        req = request_obj or request
        request_info = self._extract_request_info(req)
        
        self.info(
            f"HTTP请求开始: {req.method} {req.path}",
            extra={
                'event': 'request_start',
                'request_info': request_info
            },
            auto_format=False  # 使用原始格式
        )
    
    def log_request_success(self, request_obj=None, response_obj=None, response_time=None):
        """
        记录请求成功
        
        Args:
            request_obj: Flask request对象
            response_obj: Flask response对象
            response_time: 响应时间（毫秒）
        """
        req = request_obj or request
        request_info = self._extract_request_info(req)
        response_info = self._extract_response_info(response_obj) if response_obj else None
        
        extra_data = {
            'event': 'request_success',
            'request_info': request_info,
            'response_info': response_info
        }
        
        if response_time:
            extra_data['response_time_ms'] = response_time
        
        self.info(
            f"HTTP请求成功: {req.method} {req.path}",
            extra=extra_data,
            auto_format=False  # 使用原始格式
        )
    
    def log_request_error(self, request_obj=None, error=None, status_code=None, response_time=None):
        """
        记录请求错误
        
        Args:
            request_obj: Flask request对象
            error: 错误信息
            status_code: HTTP状态码
            response_time: 响应时间（毫秒）
        """
        req = request_obj or request
        request_info = self._extract_request_info(req)
        
        extra_data = {
            'event': 'request_error',
            'request_info': request_info,
            'error': str(error) if error else None,
            'status_code': status_code
        }
        
        if response_time:
            extra_data['response_time_ms'] = response_time
        
        # 构建详细的错误日志消息
        log_message = f"HTTP请求错误: {req.method} {req.path} - {error}"
        if response_time:
            log_message += f" (响应时间: {response_time}ms)"
        
        self.error(log_message, extra=extra_data, auto_format=False)  # 使用原始格式
    
    def log_request_complete(self, message, request_obj=None, response_obj=None, response_time=None):
        """
        记录完整的请求信息（包含请求和响应详情）
        
        Args:
            message: 日志消息
            request_obj: Flask request对象
            response_obj: Flask response对象
            response_time: 响应时间（毫秒）
        """
        req = request_obj or request
        request_info = self._extract_request_info(req)
        response_info = self._extract_response_info(response_obj) if response_obj else None
        
        # 构建详细的日志消息
        log_message = f"{message}\n[REQUEST] {json.dumps(request_info, ensure_ascii=False, indent=2)}"
        
        if response_info:
            log_message += f"\n[RESPONSE] {json.dumps(response_info, ensure_ascii=False, indent=2)}"
        
        if response_time:
            log_message += f"\n[RESPONSE_TIME] {response_time}ms"

        # 根据状态码选择日志级别
        if response_info and 'status_code' in response_info:
            status_code = response_info['status_code']
            if status_code >= 500:
                self.error(log_message, auto_format=False)
            elif status_code >= 400:
                self.error(log_message, auto_format=False)
            else:
                self.info(log_message, auto_format=False)
        else:
            # 如果没有状态码信息，默认使用INFO级别
            self.info(log_message, auto_format=False)
    
    def _extract_request_info(self, request_obj):
        """提取请求信息"""
        if not request_obj:
            return {}
        
        info = {
            'method': request_obj.method,
            'url': request_obj.url,
            'path': request_obj.path,
            'args': dict(request_obj.args),
            'remote_addr': request_obj.remote_addr,
            'user_agent': str(request_obj.user_agent)
        }
        
        # 添加表单数据
        if request_obj.form:
            info['form'] = dict(request_obj.form)
        
        # 添加JSON数据
        try:
            json_data = request_obj.get_json(silent=True)
            if json_data:
                info['json'] = json_data
        except:
            pass
        
        # 添加完整的头部信息
        headers = self._extract_headers(request_obj.headers)
        if headers:
            info['headers'] = headers
        
        return info
    
    def _extract_headers(self, headers_obj):
        """
        提取完整的headers信息，对敏感信息进行脱敏
        
        Args:
            headers_obj: Flask headers对象
        
        Returns:
            dict: 处理后的headers字典
        """
        if not headers_obj:
            return {}
        
        headers = {}
        
        for header_name in headers_obj.keys():
            header_value = headers_obj.get(header_name, '')
            
            # 处理敏感信息脱敏
            if header_name.lower() == 'authorization':
                # Authorization header脱敏
                if header_value.startswith('Bearer '):
                    header_value = 'Bearer ***'
                elif header_value.startswith('Basic '):
                    header_value = 'Basic ***'
                else:
                    header_value = '***'
            elif header_name.lower() == 'cookie':
                # Cookie header脱敏（只显示前100字符）
                if len(header_value) > 100:
                    header_value = header_value[:100] + '...[脱敏]'
            
            headers[header_name] = header_value
        
        return headers
    
    def _extract_response_info(self, response_obj):
        """提取响应信息"""
        if not response_obj:
            return {}
        
        info = {
            'status_code': response_obj.status_code,
            'mimetype': getattr(response_obj, 'mimetype', 'unknown')
        }
        
        # 添加响应头部
        if hasattr(response_obj, 'headers'):
            important_headers = ['content-type', 'content-length']
            headers = {}
            for header in important_headers:
                if header in response_obj.headers:
                    headers[header] = response_obj.headers[header]
            if headers:
                info['headers'] = headers
        
        return info
    
    def log_api_call(self, endpoint, method, params=None, result=None, error=None, response_time=None):
        """
        记录API调用
        
        Args:
            endpoint: API端点
            method: HTTP方法
            params: 请求参数
            result: 返回结果
            error: 错误信息
            response_time: 响应时间（毫秒）
        """
        extra_data = {
            'event': 'api_call',
            'endpoint': endpoint,
            'method': method,
            'params': params,
            'result': result,
            'error': error,
            'response_time_ms': response_time
        }
        
        if error:
            self.error(f"API调用失败: {endpoint} - {error}", extra=extra_data)
        else:
            self.info(f"API调用成功: {endpoint}", extra=extra_data)